package com.chunqiu.game.wuziqi.websocket;

import com.alibaba.fastjson.JSON;
//import com.chunqiu.game.wuziqi.websocket.entity.WUZIQIMessageBody;
import com.chunqiu.game.wuziqi.websocket.entity.WUZIQIMessageBody;
import com.chunqiu.game.wuziqi.websocket.entity.WuZiQiRoomInfo;
import com.ruoyi.common.utils.RandomUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.common.websocket.WebSocketMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import reactor.util.annotation.NonNull;

import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class ChatWebSocketHandler extends TextWebSocketHandler {

    // 使用Map来存储会话ID和对应的WebSocket会话集合
    private final Map<String, Set<WebSocketSession>> roomMap = new ConcurrentHashMap<>();

    private final Map<String, String> sessionRoomIdMap = new ConcurrentHashMap<>();

    private final Map<String, WuZiQiRoomInfo> roomInfoMap = new ConcurrentHashMap<>();

    @Override
    public void afterConnectionEstablished(@NonNull WebSocketSession session) throws Exception {
        log.info("session为{}的用户连接了websocket", session.getId());
    }

    @Override
    protected void handleTextMessage(@NonNull WebSocketSession session, @NonNull TextMessage message) throws IOException {
        if (ObjectUtils.isEmpty(message)) {
            log.error("传递的message数据为空");
            return;
        }
        String jsonString = message.getPayload();
        WebSocketMessage webSocketMessage = JSON.parseObject(jsonString, WebSocketMessage.class);
        if (ObjectUtils.isEmpty(webSocketMessage)) {
            log.error("转化的webSocketMessage数据为空");
            return;
        }
        // 从消息中提取会话ID（这里假设会话ID是消息的前缀，实际实现可能不同）
        String to;
        boolean isSuccess;
        WuZiQiRoomInfo roomInfo;
        Set<WebSocketSession> sessions;
        WebSocketMessage wuziqiMessage;
        switch (webSocketMessage.getMessageType()) {
            case WebSocketMessage.ROOM_CREATE:
                to = UUID.randomUUID().toString();
                isSuccess = addSessionToRoom(to, session); // 是否加入成功
                String user = RandomUtils.generateEasyRandomCode(); //定义用户名
                roomInfo = addUserToRoom(to, user, session.getId()); // 将用户添加到房间信息
                wuziqiMessage = buildWuziqiWebSocketMessage(buildWuziqiMessageBody(roomInfo));
                webSocketMessage.setTo(to);
                session.sendMessage(webSocketMessage.toTextMessage());
                session.sendMessage(wuziqiMessage.toTextMessage());
                break;
            case WebSocketMessage.ROOM_JOIN:
                to = webSocketMessage.getTo();
                isSuccess = addSessionToRoom(to, session);
                if (isSuccess) {
                    String from = RandomUtils.generateEasyRandomCode();
//                    addUserToRoom(to, from, session.getId()); // 将用户添加到房间信息
                    roomInfo = addUserToRoom(to, from, session.getId()); // 将用户添加到房间信息
                    wuziqiMessage = buildWuziqiWebSocketMessage(buildWuziqiMessageBody(roomInfo));

                    webSocketMessage.setFrom(from);
                    webSocketMessage.setTo(to);
                    session.sendMessage(webSocketMessage.toTextMessage());

                    webSocketMessage.setMessage(from + "已加入房间");
                    webSocketMessage.setFrom("系统");
                    webSocketMessage.setMessageType(WebSocketMessage.ROOM_TEXT);
                    sessions = roomMap.get(to);
                    for (WebSocketSession webSocketSession : sessions) {
                        try {
                            if (webSocketSession.isOpen()) {
                                webSocketSession.sendMessage(webSocketMessage.toTextMessage());
                                webSocketSession.sendMessage(wuziqiMessage.toTextMessage());
                            }
                        } catch (IOException e) {
                            log.error("发生错误", e);
                        }
                    }
                }

                break;
            case WebSocketMessage.ROOM_TEXT:
                to = webSocketMessage.getTo();
                sessions = roomMap.get(to);
                if (sessions == null) {
                    log.error("错误的房间号");
                    WebSocketMessage temp = new WebSocketMessage();
                    temp.setMessage("错误的房间号");
                    temp.setMessageType(WebSocketMessage.ROOM_TEXT);
                    temp.setFrom("系统");
                    temp.setTo(to);
                    temp.setStatus("500");
                    temp.setCreateTime(new Date());
                    session.sendMessage(temp.toTextMessage());
                    return;
                }
                for (WebSocketSession webSocketSession : sessions) {
                    try {
                        if (webSocketSession.isOpen()) {
                            webSocketSession.sendMessage(message);
                        }
                    } catch (IOException e) {
                        log.error("发生错误", e);
                    }
                }
                break;
            case WebSocketMessage.WUZIQI:
                to = webSocketMessage.getTo(); // roomId
                sessions = roomMap.get(to);
                if (sessions == null) {
                    log.error("此房间不存在");
                    WebSocketMessage temp = new WebSocketMessage();
                    temp.setMessageType(WebSocketMessage.ROOM_TEXT);
                    temp.setFrom("系统");
                    temp.setStatus("500");
                    temp.setCreateTime(new Date());
                    temp.setMessage("此房间不存在");
                    session.sendMessage(temp.toTextMessage());
                    return;
                } else {
                    roomInfo = roomInfoMap.get(to);
                    WUZIQIMessageBody wuziqiMessageBody = JSON.parseObject(webSocketMessage.getMessage(), WUZIQIMessageBody.class);
                    WUZIQIMessageBody result = roomInfo.updateRoomInfo(wuziqiMessageBody);
                    WebSocketMessage temp = new WebSocketMessage();
                    temp.setMessageType(WebSocketMessage.WUZIQI);
                    temp.setFrom("系统");
                    temp.setStatus("0");
                    temp.setCreateTime(new Date());
                    temp.setMessage(JSON.toJSONString(result));
                    if(result.getType().equals("ERROR") || result.getType().equals("CHECK_WIN")) {
                        // 错误信息只发送给原用户
                        session.sendMessage(temp.toTextMessage());
                        return;
                    }
                    for (WebSocketSession webSocketSession : sessions) {
                        try {
                            if (webSocketSession.isOpen()) {
                                webSocketSession.sendMessage(temp.toTextMessage());
                            }
                        } catch (IOException e) {
                            log.error("发生错误", e);
                        }
                    }
                }
                break;
        }
    }

    private WUZIQIMessageBody buildWuziqiMessageBody(WuZiQiRoomInfo roomInfo) {

        WUZIQIMessageBody wuziqiMessageBody = new WUZIQIMessageBody();
        wuziqiMessageBody.setValue(roomInfo);
        wuziqiMessageBody.setType("JOIN_ROOM");
//        wuziqiMessage.setMessage(JSON.toJSONString(wuziqiMessageBody));
        return wuziqiMessageBody;
    }

    private WebSocketMessage buildWuziqiWebSocketMessage(WUZIQIMessageBody messageBody) {
        WebSocketMessage wuziqiMessage = new WebSocketMessage();
        wuziqiMessage.setFrom("系统");
        wuziqiMessage.setTo("");
        wuziqiMessage.setMessageType(WebSocketMessage.WUZIQI);
        wuziqiMessage.setStatus("0");
        wuziqiMessage.setCreateTime(new Date());
        wuziqiMessage.setMessage(JSON.toJSONString(messageBody));
        return wuziqiMessage;
    }

    // 当新会话建立时，需要调用这个方法来将会话添加到sessionMap中
    public boolean addSessionToRoom(String roomId, WebSocketSession session) {
        sessionRoomIdMap.put(session.getId(), roomId);
        Set<WebSocketSession> sessions = roomMap.get(roomId);
        if (sessions == null) {
            sessions = new HashSet<>();
        }
        sessions.add(session);
        roomMap.put(roomId, sessions);
        return true;
    }

    public WuZiQiRoomInfo addUserToRoom(String roomId, String user, String sessionId) {
        // 房间加入，更新房间信息
        WuZiQiRoomInfo roomInfo = roomInfoMap.get(roomId);
        if(roomInfo == null) {
            roomInfo = new WuZiQiRoomInfo();
        }
        roomInfo.joinUser(user, sessionId);
        roomInfoMap.put(roomId, roomInfo);
        return roomInfo;
    }

    // 辅助方法：从房间中移除会话
    private void removeFromRoom(WebSocketSession session) {
        String roomId = sessionRoomIdMap.get(session.getId());
        Set<WebSocketSession> sessions = roomMap.get(roomId);
        if (sessions != null) {
            sessions.remove(session);
            sessionRoomIdMap.remove(session.getId());
            System.out.println("Session removed from room: " + roomId + ", Session ID: " + session.getId());
            if (sessions.isEmpty()) {
                roomMap.remove(roomId);
                roomInfoMap.remove(roomId);
            }
            sessionRoomIdMap.remove(session.getId());
        }
    }

    private String removeUserBySession(WebSocketSession session) {
        String roomId = sessionRoomIdMap.get(session.getId());
        WuZiQiRoomInfo wuZiQiRoomInfo = roomInfoMap.get(roomId);
        String user = wuZiQiRoomInfo.getSessionUserMap().get(session.getId());
        roomInfoMap.put(roomId, wuZiQiRoomInfo.removeUserBySessionId(session.getId()));
        return user;
    }


    @Override
    public void afterConnectionClosed(@NonNull WebSocketSession session, @NonNull CloseStatus status) throws Exception {
        // 从消息中提取会话ID（这里假设会话ID是消息的前缀，实际实现可能不同）
        String roomId = sessionRoomIdMap.get(session.getId());
        String user = removeUserBySession(session);
        removeFromRoom(session);
        WebSocketMessage message = new WebSocketMessage();
        message.setMessageType(WebSocketMessage.ROOM_TEXT);
        message.setStatus("0");
        message.setCreateTime(new Date());
        message.setFrom("系统");
        message.setMessage(user+"已退出房间");

        WuZiQiRoomInfo wuZiQiRoomInfo = roomInfoMap.get(roomId);
        WebSocketMessage wuziqiMessage = new WebSocketMessage();
        WUZIQIMessageBody wuziqiMessageBody = new WUZIQIMessageBody();
        wuziqiMessageBody.setValue(wuZiQiRoomInfo);
        wuziqiMessage.setMessageType(WebSocketMessage.WUZIQI);
        wuziqiMessage.setStatus("0");
        wuziqiMessage.setCreateTime(new Date());
        wuziqiMessage.setFrom("系统");
        wuziqiMessage.setMessage(JSON.toJSONString(wuziqiMessageBody));

        // 向房间内其他人发送信息并更新房间信息
        Set<WebSocketSession> sessions = roomMap.get(roomId);
        if(sessions != null){
            for (WebSocketSession webSocketSession : sessions) {
                webSocketSession.sendMessage(message.toTextMessage());
                webSocketSession.sendMessage(wuziqiMessage.toTextMessage());
            }
        }
        System.out.println("Session closed: " + session.getId());
    }
}